﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Media;
using System.Reflection;
using System.Windows.Forms;
using System.Net.NetworkInformation;
using Microsoft.Win32;

namespace ImapNotify {

    /*
     *  This is a startup form. It is hidden. It is shown only to enter configuration,
     *  it shows only tray notifyIcon
     */
    public partial class frmDialog : Form {

		private bool reallyClose = false;
		private Icon IconOld;
		private string soundPath;

        private bool connectionERR; //Properties.Settings.Default.GmailLessSecApp has link about "less secure app" in Google account
        private InternetLog internetLog;
        private bool advancedView = false;

		public frmDialog() {

			InitializeComponent();

            internetLog= new InternetLog();
            timer.Interval = Properties.Settings.Default.Interval;
            this.Text = this.Text +"  "+ Application.ProductVersion; //AssemblyInformation File Version
			IconOld = this.notifyIcon.Icon;
			soundPath = Path.GetDirectoryName(	Assembly.GetExecutingAssembly().Location) + @"\Notify.wav";
			if (!File.Exists(soundPath)) {soundPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Media\Windows Notify.wav";	}
			this.Location = new Point( Screen.PrimaryScreen.WorkingArea.Width - Width, Screen.PrimaryScreen.WorkingArea.Height - Height);

			NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(OnNetworkAvailabilityChanged);
			SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(OnPowerModeChanged);
			Imap.NewMessageEvent += new NewMessageEventHandler(OnNewMessage);

            connectionERR = false;
			try {
				if (Properties.Settings.Default.Username == "" ||
					Properties.Settings.Default.Password == "")   {
					//notifyIcon.ShowBalloonTip(300, "First Run?", "Right-cick icon to configure settings.", ToolTipIcon.Info);
                    Show(); WindowState = FormWindowState.Normal; Focus(); 
				} else {
					Imap.Start();
					CheckNewMail();
				}
			} catch (Exception ex) {
				this.notifyIcon.ShowBalloonTip(300, "Error connecting to host. (1)",
                    "Please see this article:"+ Environment.NewLine +
                    Properties.Settings.Default.GmailLessSecApp + Environment.NewLine + Environment.NewLine + 
                    ex.Message,
					ToolTipIcon.Error);
                connectionERR = true;
                //Util.WriteEventLog("Error connecting to host (1)");
			}
		}//end:constructor




   /*
    *   O N   N E W   M E S S A G E
    */
		private void OnNewMessage(object sender, NewMessageEventArgs e) {

            notifyIcon.ShowBalloonTip(300,
                "New e-mail.  (" + e.UnreadMails + " unread.)", 
                    "From: "+e.Message.From + Environment.NewLine + 
                    "Subject: "+e.Message.Subject, ToolTipIcon.Info );
			if (Properties.Settings.Default.PlaySound) { try {(new SoundPlayer(soundPath)).Play();} catch (Exception) { } }
			UpdateTrayIcon(e.UnreadMails);
		}

#region Notify icon events
       
        private void notifyIcon_BalloonTipClicked(object sender, EventArgs e) {

            if ((Control.MouseButtons & MouseButtons.Right) == MouseButtons.Right) return; // --- >
           
            string site = connectionERR ? Properties.Settings.Default.GmailLessSecApp : getMailLink();
			if (site != "")	Process.Start(site);
			notifyIcon.Icon = IconOld;
		}
		private void notifyIcon_MouseClick(object sender, MouseEventArgs e) { // event for dbl-click

			if (e.Button == MouseButtons.Left) {
                string site = getMailLink(); 
				if (site != "")	Process.Start(site);
				notifyIcon.Icon = IconOld;
			}
		}

        private string getMailLink() {
            return Properties.Settings.Default.UseGmail ?
                   Properties.Settings.Default.GmailWebsite :
                   Properties.Settings.Default.URL;
        }
#endregion



        private void timer_Tick(object sender, EventArgs e) {

			if (Util.IsInternetConnected()) {
                internetLog.AddEvent(currentStatus: true);
				if (Imap.Started())
					UpdateTrayIcon(Imap.GetUnreadCount());
				else {
					/* attempt to silently reconnect */
                    Reconnect(checkForNewMails:false);
				}
			} else {
                internetLog.AddEvent(currentStatus: false, notifyIcon: notifyIcon);
				/* Stop if not connected to the internet */
				Imap.Stop();
                Util.WriteEventLog("timer_Tick() - internet disconnected."); 
			}
		}

		private void UpdateTrayIcon(int Count) {
			if (Count > 0) {
				notifyIcon.Text = Count.ToString() + " unread message" + (Count > 1 ? "s" : "");
                notifyIcon.Icon = Properties.Resources.newMail;
			} else {
				notifyIcon.Text = "No new messages";
				notifyIcon.Icon = IconOld;
			}
		}

		private void CheckNewMail() {
			int Count = Imap.GetUnreadCount();
			if (Count > 0) {
				notifyIcon.ShowBalloonTip(300, "New e-mail", Count.ToString() +	" unread message" + (Count > 1 ? "s" : ""), ToolTipIcon.Info);
				if (Properties.Settings.Default.PlaySound) {try { (new SoundPlayer(soundPath)).Play(); } catch (Exception) { }	}
			}
			UpdateTrayIcon(Count);
		}




		private void Reconnect(bool checkForNewMails = true) {
            connectionERR = false;
			try {
				Imap.Stop();
				Imap.Start();
				if (checkForNewMails)
					CheckNewMail();
			} catch (Exception ex) {
				notifyIcon.ShowBalloonTip(500, "Error connecting to host. (2)", ex.Message,	ToolTipIcon.Error);
                connectionERR = true;
                //Util.WriteEventLog("Error connecting to host (2)");
			}
		}

		private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) {
			/* Unfortunately this seems unreliable, so whenever network availability changes
			 * we disconnect and let the tick event take care of reconnecting */
			Imap.Stop();
		}

		private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e) {
			if (e.Mode == PowerModes.Suspend)
				Imap.Stop();
		}




#region form events
        private void Dialog_Load(object sender, EventArgs e) {
            textPassword.Text = Encryption.DecryptString(Properties.Settings.Default.Password);
            EnableFields(!Properties.Settings.Default.UseGmail);
        }
        private void Dialog_FormClosing(object sender, FormClosingEventArgs e) {
            if (!reallyClose) {
                e.Cancel = true;
                WindowState = FormWindowState.Minimized;
            }
        }
        private void Dialog_FormClosed(object sender, FormClosedEventArgs e) {
            if (reallyClose)
                Application.Exit();
        }
        private void Dialog_Resize(object sender, EventArgs e) {
            if (FormWindowState.Minimized == WindowState)
                Hide();
        }
#endregion

#region form controls events

        private void EnableFields(bool enable) {
            labelImapServer.Enabled = enable;
            labelServerPort.Enabled = enable;
            labelURL.Enabled = enable;
            textImapServer.Enabled = enable;
            textServerPort.Enabled = enable;
            textURL.Enabled = enable;
            useSSL.Enabled = enable;
        }
        private void useGmail_CheckedChanged(object sender, EventArgs e) {
            EnableFields(!useGmail.Checked);
            buttonApply.Enabled = true;
        }
        private void buttonApply_Click(object sender, EventArgs e) {
            Properties.Settings.Default.Password = Encryption.EncryptString(textPassword.Text);
            Properties.Settings.Default.Save();
            Util.RunOnStartup(Properties.Settings.Default.AutoRun);

            buttonApply.Enabled = false;
            Reconnect();
        }
        private void text_TextChanged(object sender, EventArgs e) {
            if (((TextBox)sender).ContainsFocus)
                buttonApply.Enabled = true;
        }
        private void checkBoxChanged(object sender, EventArgs e) {
            if (((CheckBox)sender).ContainsFocus)
                buttonApply.Enabled = true;
        }
        private void textURL_Enter(object sender, EventArgs e) {
            tipURL.Show("URL to go to when clicking on\ntrayicon or balloontip. If none,\njust leave empty.", textURL);
        }
        private void lnkGmailInfo1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
            Process.Start(Properties.Settings.Default.GmailLessSecApp);
        }

        private void lnkLogShow_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {

            int count;
            var txt = internetLog.getLog(out count);
            string c = count == 0 ? "" : " " + count.ToString();
            MessageBoxIcon ico = MessageBoxIcon.Exclamation;
            if (txt == "") { txt = "No interruptions logged."; ico = MessageBoxIcon.Information; }

            MessageBox.Show(txt, "Internet Service Interruptions" + c, MessageBoxButtons.OK, ico);

        }
        private void lnkLogCopy_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
            string txt = internetLog.getReport();
            if (!String.IsNullOrEmpty(txt))
                System.Windows.Forms.Clipboard.SetText(txt);
        }

        private void lnkLogClear_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
            internetLog.clearLog();
        }

        private void lnkAdvanced_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
            int h = 80;
            if (advancedView) { this.Height -= h; this.Top += h; lnkAdvanced.Text = "advanced"; }
            else {              this.Height += h; this.Top -= h; lnkAdvanced.Text = "normal view"; }
            advancedView = !advancedView;
        }
#endregion

#region Notify Icon Context menuMenu

        private void contextMenuQuit_Click(object sender, EventArgs e) {
            reallyClose = true;
            Close();
            Imap.Stop();
            Application.Exit();
        }
        private void contextMenuConfigure_Click(object sender, EventArgs e) {
            Show();
            WindowState = FormWindowState.Normal;
            Focus();
        }
        private void contextMenuReconnect_Click(object sender, EventArgs e) {
            notifyIcon.ShowBalloonTip(300, "", "connecting ...", ToolTipIcon.Info);
            Reconnect();
            int Count = Imap.GetUnreadCount();
            notifyIcon.ShowBalloonTip(300, "", Count.ToString() + " unread message" + ((Count > 1)|(Count==0) ? "s" : ""), ToolTipIcon.Info);
        }
        private void contextMenuMail_Click(object sender, EventArgs e) {
            string site = getMailLink();
            if (site != "") Process.Start(site);
            notifyIcon.Icon = IconOld;
        }
#endregion





 
	}//end:form
}//end:namespace
